package com.pwc.conversionTool.task;

import static com.pwc.conversionTool.IO.Writer.writeStringToFile;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.map.HashedMap;
import org.dom4j.DocumentException;
import org.hibernate.id.enhanced.OptimizerFactory.InitialValueAwareOptimizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.eviware.soapui.model.iface.Request.SubmitException;
import com.pwc.conversionTool.IO.FileOperation;
import com.pwc.conversionTool.IO.Reader;
import com.pwc.conversionTool.Manager.WsdlXmlConfigImpl;
import com.pwc.conversionTool.Manager.XMLConfigImpl;
import com.pwc.conversionTool.csv.CsvHelper;
import com.pwc.conversionTool.rest.SoapRest;
import com.pwc.conversionTool.soapUI.SoapUIClient;

public class Task implements Runnable {

	// something for config

	// something about the dataSource for uploading

	// status

	private static final Logger logger = LoggerFactory.getLogger(Task.class);

	public ServletContext context;
	private SoapUIClient client;
	private WsdlXmlConfigImpl wsdlXmlConfigImpl;
	private String taskName;
	private List<String> csvFiles;
	private String relationFile;
	
	private String content = null;//
	private JSONArray jsonarray;
	private JSONObject jsonObject;
	private String key = null;
	private String value = null;
	
	private String operationName;
	private List<String> operationDataList;

	volatile boolean stop = false;

	public Task() {

	}

	public Task(ServletContext context, List<String> csvFiles,
			String relationFile, String taskName) {
		super();
		this.context = context;
		this.taskName = taskName;
		this.csvFiles = csvFiles;
		this.relationFile = relationFile;
	}

	public String getTaskName() {
		return taskName;
	}

	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

	public boolean isStop() {
		return stop;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}

	public String getTaskStatus() {
		if (stop) {
			return "Stop";
		} else {
			return "Runing";
		}
	}

	/*initial client
	 * */
	public void Initial() throws IOException, DocumentException {
		client = new SoapUIClient();// initial....
		content = Reader.getStringFromFile(this.relationFile);
		jsonarray = JSONArray.fromObject(content);
		jsonObject = jsonarray.getJSONObject(0);
		client.initialProject(jsonObject.getString("endpoint"));
		wsdlXmlConfigImpl = WsdlXmlConfigImpl.InitialString(client.getTemplate(jsonObject.getString("operationName")));
		operationName=jsonObject.getString("operationName");
		operationDataList=new ArrayList<String>();
	}

	
	/*mapping data
	 * */
	private boolean MappingData(String csvFile) throws IOException, SubmitException {
		JSONArray jsonarray_mappingData = JSONArray.fromObject(jsonObject.get("mappingData"));
		JSONObject jsonObject_mappingData = jsonarray_mappingData.getJSONObject(0);
		Iterator iterator_mapping = jsonObject_mappingData.keys();

		List<String> mappingHead = new ArrayList<String>();//csv head data
		
		ArrayList<List<String>> mappingAllList = new ArrayList<List<String>>();//csv content data
		int csv_data_column = 0;
		int csv_data_row = 0;
		
		// mapping data
		while (iterator_mapping.hasNext()) {
			int k = 0;//mapping_row
			
			key = (String) iterator_mapping.next();
			value = jsonObject_mappingData.getString(key);
			mappingHead.add(key);

			List<String[]> list = new CsvHelper(csvFile).getAll();
			int mapping_column;
			for (mapping_column= 0; mapping_column < list.get(0).length; mapping_column++) {
				if (value.equals(list.get(0)[mapping_column])) {
					break;
				}
			}
			// csv is not mapping,skip
			if (mapping_column == list.get(0).length) {
				return false;
			}
			list.remove(0);
			ArrayList<String> mappingList = new ArrayList<String>();//csv column
			
			// mappingList.add(list[i]);
			for (String[] string : list) {
				mappingList.add(string[mapping_column]);
				k++;
			}

			mappingAllList.add(mappingList);
			csv_data_column++;
			csv_data_row = k;
		}
		GenerateSendXML(mappingHead,mappingAllList,csv_data_row,csv_data_column);
		return true;
	}
	
	/*generate soap log
	 * */
	private void GenerateSendXML(List<String> mappingHead,ArrayList<List<String>> mappingAllList,int csv_data_row, int csv_data_column) throws IOException, SubmitException{
		for (int i = 0; i < csv_data_row; i++) {
			for (int j = 0; j < csv_data_column; j++) {
				wsdlXmlConfigImpl.setSingleStringValue(mappingHead.get(j),mappingAllList.get(j).get(i));
			}
			operationDataList.add(wsdlXmlConfigImpl.getXMLString());
		}
	}

	/*delete xpath
	 * */
	private void DeleteData() {
		JSONArray jsonarray_deleteData = JSONArray.fromObject(jsonObject
				.get("deleteData"));
		JSONObject jsonObject_deleteData = jsonarray_deleteData
				.getJSONObject(0);
		Iterator iterator_delete = jsonObject_deleteData.keys();
		// delete xpath
		while (iterator_delete.hasNext()) {
			key = (String) iterator_delete.next();
			value = jsonObject_deleteData.getString(key);
			wsdlXmlConfigImpl.deleteNodeByXpath(value);
		}
	}

	/*set security
	 * */
	private void Security() throws DocumentException {
		String userName = XMLConfigImpl.initial(context).getUserName();
		String password = XMLConfigImpl.initial(context).getPassword();
		String passwordType = XMLConfigImpl.initial(context).getPasswordType();
		if (userName.length() > 0 && password.length() > 0
				&& passwordType.equals("PasswordText")) {
			client.setSecurity(userName, password, passwordType);
		} else if (userName.length() > 0 && password.length() > 0) {
			client.setSecurity(userName, password);
		}
	}
	
	/*send soap
	 * */
	private String SendSoap(String operation, String data) throws SubmitException {
		client.generateWSDLRequest(operation, data);
		return client.doSubmit(operation, data);
	}
	

	// run the task
	@Override
	public void run() {

		// do initial

		// do filter //
//		try {
//			Initial();
//		} catch (IOException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		} catch (DocumentException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
		//do delete
		DeleteData();

		// do mapping
		for (String csvFile : csvFiles) {
			if (!stop) {
				try {
					MappingData(csvFile);
					FileOperation.cutFileToDirectory(new File(csvFile), new File("C:\\Users\\dwu102\\Desktop\\workday\\completeFile"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (SubmitException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}// end of foreach

		//security

		// do sending
		
		for(String operationData:operationDataList){
			try {
				Thread.sleep(1000);
				Date date=new Date();
				DateFormat format=new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
				String time=format.format(date);
				writeStringToFile(new File("C:\\Users\\dwu102\\Desktop\\workday\\soapXml\\"+taskName+"_"+time+".txt"),operationData);
				//soap log
				writeStringToFile(new File("C:\\Users\\dwu102\\Desktop\\workday\\soapXml\\log_"+taskName+"_"+time+ ".txt"),SendSoap(operationName, operationData));
				
			} catch (SubmitException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}	
		
		stop = true;

	}
}
